home *** CD-ROM | disk | FTP | other *** search
/ The Best of MacTutor - S…e Code for Volumes 1 to 5 / The Best of MacTutor - Source Code for Volume 1-5 (Wayzata Technology)(6031)(1990).bin / Source Code / #11 (Aug 86) / c / menu.c < prev    next >
C/C++ Source or Header  |  1986-06-30  |  6KB  |  334 lines

  1. /* menu and window manager demonstration 
  2.  * base on program in 
  3.  * Using Macintosh Toolbox with C
  4.  * page 91
  5.  *
  6.  *    Compiled with LightspeedC
  7.  *
  8.  *    Important note for Mac C users:
  9.  *        Everyplace you see event->where,
  10.  *        replace it with &event->where
  11.  */
  12.  
  13.  
  14.  #include    "abc.h"
  15.  #include    "Events.h"
  16.  #include    "Window.h"
  17.  #include    "Menu.h"
  18.  
  19.  /* defines for menu ID's */
  20.  
  21.  #define        Mdesk        100
  22.  #define        Mfile        101
  23.  #define        Medit        102
  24.  #define        Mwind        103
  25.  #define        Mtest        104
  26.  
  27.  /* Global variables */
  28.  
  29.  MenuHandle        menuDesk;    /* menu handles */
  30.  MenuHandle        menuFile;
  31.  MenuHandle        menuEdit;
  32.  MenuHandle        menuWind;
  33.  MenuHandle        menuTest;
  34.  
  35.  
  36.  WindowPtr        theWindow;
  37.  WindowRecord    windowRec;
  38.  Rect                dragbound;
  39.  Rect                limitRect;
  40.  
  41. main()
  42. {
  43.     initsys();    /* system initialization */
  44.     initapp();    /* application initialization */
  45.     eventloop();
  46. }
  47.  
  48.  
  49. /* system initialization 
  50.  *        note use of hard coded screen sizes
  51.  *        with LightspeedC.  This will work
  52.  *        with other compilers but is not
  53.  *        good practice
  54.  */
  55. initsys()        
  56. {                    
  57.     InitGraf(&thePort);    /* these two lines done */
  58.     InitFonts();            /* automatically by Mac C */
  59.     InitWindows();
  60.     InitCursor();
  61.     InitMenus();
  62.     theWindow = Nil;        /*indicates no window */
  63.     SetRect(&dragbound,0,0,512,342);
  64.     SetRect(&limitRect,60,40,508,318);
  65. }
  66.  
  67.  
  68. /*
  69.  *    application initialization
  70.  *        Sets up menus.
  71.  *        Each menu is a separate group
  72.  *        of lines.  Note the last menu
  73.  *        is appended but not inserted.  This
  74.  *        makes it part of the menu list but 
  75.  *        not in the menu bar.
  76.  */
  77. initapp()
  78. {
  79.     menuDesk = NewMenu(Mdesk,CtoPstr("\24"));
  80.     AddResMenu (menuDesk, 'DRVR');
  81.     InsertMenu (menuDesk, 0);
  82.     
  83.     menuFile = NewMenu(Mfile, CtoPstr("File"));
  84.     AppendMenu (menuFile, 
  85.         CtoPstr("Open Window/M;Close Window/X;Quit/Q"));
  86.     AppendMenu (menuFile, 
  87.         CtoPstr("(-;Show Test;(Hide Test"));
  88.     InsertMenu (menuFile, 0);
  89.     
  90.     menuEdit = NewMenu(Medit, CtoPstr("Edit"));
  91.     AppendMenu (menuEdit, 
  92.         CtoPstr("Undo;(-;Cut;Copy;Paste;Clear"));
  93.     InsertMenu (menuEdit, 0);
  94.     
  95.     menuWind = NewMenu(Mwind, CtoPstr("Window"));
  96.     AppendMenu (menuWind, 
  97.         CtoPstr("Hide;Show;New Title"));
  98.     InsertMenu (menuWind, 0);
  99.     
  100.     menuTest = NewMenu(Mtest, CtoPstr("Test"));
  101.     AppendMenu (menuTest, 
  102.         CtoPstr("Pick;One;Of;These"));
  103.     
  104.     DrawMenuBar();
  105. }
  106.     
  107.     
  108. /*    Event Loop 
  109.  *        Loop forever until Quit
  110.  */
  111. eventloop()
  112. {
  113.     EventRecord        theEvent;
  114.     char                c;
  115.     short                windowcode;
  116.     WindowPtr        ww;
  117.     
  118.     while(True)
  119.         {
  120.         if (theWindow)                    /* this code is here to */
  121.             {                                /* prevent closing an */
  122.             EnableItem(menuFile,2);    /* already closed window */
  123.             DisableItem(menuFile,1);
  124.             }
  125.         else                                
  126.             {                                
  127.             EnableItem(menuFile,1);
  128.             DisableItem(menuFile,2);
  129.             }
  130.             
  131.         if (GetNextEvent(everyEvent,&theEvent))
  132.             switch(theEvent.what)                    
  133.                 {                        /* only check key and */
  134.                 case keyDown:         /* mouse down events */
  135.                     if (theEvent.modifiers & cmdKey)
  136.                         {
  137.                         c = theEvent.message & charCodeMask;
  138.                         domenu(MenuKey(c));
  139.                         }
  140.                     break;
  141.                 case mouseDown:
  142.                     domouse(&theEvent);
  143.                     break;
  144.                 default:
  145.                     break;
  146.                 }
  147.         }
  148. }
  149.  
  150.  
  151. /* domouse
  152.  *        handle mouse down events
  153.  */
  154. domouse(er)
  155.     EventRecord    *er;
  156. {
  157.     short            windowcode;
  158.     WindowPtr    whichWindow;
  159.     short            ingo;
  160.     long            size;
  161.     
  162.     windowcode = FindWindow(er->where, 
  163.                                     &whichWindow);
  164.     switch (windowcode)
  165.         {
  166.         case inDesk:
  167.             if (theWindow notequal 0)
  168.                 {
  169.                 HiliteWindow(theWindow, False);
  170.                 DrawGrowIcon(theWindow);
  171.                 }
  172.             break;
  173.         case inMenuBar:
  174.             domenu(MenuSelect(er->where));
  175.             break;
  176.         case inSysWindow:
  177.             SysBeep(1);
  178.             break;
  179.         case inContent:
  180.             HiliteWindow(whichWindow,True);
  181.             DrawGrowIcon(theWindow);
  182.             break;
  183.         case inDrag:
  184.             DragWindow(whichWindow, 
  185.                           er->where, &dragbound);
  186.             DrawGrowIcon(theWindow);
  187.             break;
  188.         case inGrow:
  189.             /* not included this month */
  190.             break;
  191.         case inGoAway:
  192.             ingo = TrackGoAway(whichWindow,er->where);
  193.             if (ingo)
  194.                 {
  195.                 CloseWindow(whichWindow);
  196.                 theWindow = Nil;
  197.                 }
  198.             break;
  199.         }
  200. }
  201.  
  202. /* domenu
  203.  *        handles menu activity
  204.  *        simply a dispatcher for each
  205.  *        menu.
  206.  */
  207. domenu(mc)
  208.     long            mc;    /* menu result */
  209. {
  210.     short            menuId;
  211.     short            menuitem;
  212.     
  213.     menuId = HiWord(mc);
  214.     menuitem = LoWord(mc);
  215.     
  216.     switch (menuId)
  217.         {
  218.         case Mdesk : break;
  219.                         /* not handling DA's */
  220.         case Mfile : dofile(menuitem);
  221.                          break;
  222.         case Medit : break;
  223.         
  224.         case Mwind : dowind(menuitem);
  225.                          break;
  226.         case Mtest : dotest(menuitem);
  227.                          break;
  228.         }
  229.     HiliteMenu(0);
  230. }
  231.  
  232. /* dofile
  233.  *        handles file menu
  234.  */
  235. dofile(item)
  236.     short        item;
  237. {
  238.     char        *title1;            /* first title for window */
  239.     Rect        boundsRect;
  240.     
  241.     switch (item)
  242.         {
  243.         case 1 :        /* open the window */
  244.             title1 = "ABC Window";
  245.             SetRect(&boundsRect,50,50,300,150);
  246.             theWindow = NewWindow(&windowRec, &boundsRect,
  247.                             CtoPstr(title1),True,documentProc,
  248.                             (WindowPtr) -1, True, 0);
  249.             DrawGrowIcon(theWindow);
  250.             PtoCstr(title1);
  251.             DisableItem(menuFile,1);
  252.             EnableItem(menuFile,2);
  253.             break;
  254.         
  255.         case 2 :        /* close the window */
  256.             CloseWindow(theWindow);
  257.             theWindow = Nil;
  258.             DisableItem(menuFile,2);
  259.             EnableItem(menuFile,1);
  260.             break;
  261.         
  262.         case 3 :        /* Quit */
  263.             ExitToShell();
  264.             break;
  265.             
  266.         case 5 :        /* Install additional menu */
  267.             InsertMenu(menuTest,0);
  268.             EnableItem(menuFile,6);
  269.             DisableItem(menuFile,5);
  270.             DrawMenuBar();
  271.             break;
  272.             
  273.         case 6 :        /* remove additional menu */
  274.             DeleteMenu(Mtest);
  275.             EnableItem(menuFile,5);
  276.             DisableItem(menuFile,6);
  277.             DrawMenuBar();
  278.             break;
  279.         
  280.         }
  281. }
  282.  
  283. /*
  284.  *    dowind
  285.  *        handles window menu 
  286.  *        Note that each case contains an
  287.  *        if testing the existance of the
  288.  *        window.  This could be written
  289.  *        with one if before the switch.
  290.  */
  291. dowind(item)
  292.     short        item;
  293. {
  294.     char        *title2;            /* second title for window */
  295.     
  296.     switch (item)
  297.         {
  298.         case 1 :    /* Hide */
  299.             if (theWindow)
  300.                 HideWindow(theWindow);
  301.             break;
  302.         case 2 :    /* Show */
  303.             if (theWindow)
  304.                 ShowWindow(theWindow);
  305.             break;
  306.         case 3 :    /* Change title */
  307.             if (theWindow)
  308.                 {
  309.                 title2 = "A Different Title";
  310.                 SetWTitle(theWindow, CtoPstr(title2));
  311.                 PtoCstr(title2);
  312.                 }
  313.             break;
  314.         }
  315. }
  316.  
  317. /*    dotest
  318.  *        Handles new menu.
  319.  *        All this does is mark menu
  320.  *        items if they are not marked and
  321.  *     unmark them if they are.
  322.  */
  323. dotest(item)
  324.     short        item;
  325. {
  326.     short        mark;
  327.     
  328.     GetItemMark(menuTest,item,&mark);
  329.     if (mark)
  330.         CheckItem(menuTest,item,False);
  331.     else
  332.         CheckItem(menuTest,item,True);
  333. }
  334.